using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.IO;
using System.Threading;
using System.Net;

using DirkRettschlag.Utils;
using System.Diagnostics;

namespace Departure
{
    public partial class frmMain : Form
    {
        Settings settings;
        frmSettings settingsForm;
        frmStationSettings stationSettingsForm;

        SkinSettings skin;

        SortedList<string, ctrlStation> stations;

        bool vga = false;
       
        public frmMain()
        {
#if DEBUG           
            Debug.WriteLine("Started: " + DateTime.Now.ToString());

            Debug.WriteLine("Initializing: " + DateTime.Now.ToString());
#endif
            settings = new Settings();
            settingsForm = new frmSettings(settings);

            skin = new SkinSettings(settingsForm.GeneralSettings.Skin + ".skin");
            skin.getSettings();

            stationSettingsForm = new frmStationSettings();
            stations = new SortedList<string, ctrlStation>();

            // http://msdn2.microsoft.com/en-us/library/aa446535.aspx

            InitializeComponent();

            this.tbcMain.Top = 0;
            this.tbcMain.Left = 0;
            this.tbcMain.Height = this.ClientSize.Height;
            this.tbcMain.Width = this.ClientSize.Width;

            SizeF currentScreen = this.CurrentAutoScaleDimensions;
            if (currentScreen.Height == 192)
            {
                vga = true;
            }
            else
            {
                vga = false;
            }

            ctrlCountdown.SkinSettings = skin;
            ctrlCountdown.VGA = vga;
#if DEBUG                        
            Debug.WriteLine("Initialized: " + DateTime.Now.ToString());
#endif
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            try
            {
#if DEBUG
                Debug.WriteLine("Loading: " + DateTime.Now.ToString());
#endif
                timerLoad.Enabled = true;

                SetFullScreen(settingsForm.GeneralSettings.FullScreen);

                tmrRefresh.Interval = Convert.ToInt32(settingsForm.GeneralSettings.UpdateInterval) * 60 * 1000;

                if (settingsForm.GeneralSettings.AutoUpdate)
                {
                    tmrRefresh.Enabled = true;
                    tmrRefresh_Tick(null, null);
                }

                tmrRemove.Enabled = settingsForm.GeneralSettings.RemovePastDepartures;
#if DEBUG
                Debug.WriteLine("Loaded: " + DateTime.Now.ToString());
#endif
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "An error occured");
            }

        }

        private void frmMain_Closing(object sender, CancelEventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            SaveStations();
            Cursor.Current = Cursors.Default;
        }

        private void frmMain_Resize(object sender, EventArgs e)
        {
            //ResizeColumns(lsvMainStation1);
            //ResizeColumns(lsvMainStation2);
            //ResizeColumns(lsvMainStation3);
            //ResizeColumns(lsvMainStation4);

        }

        private void LoadStations()
        {
            string[] tmpStations = settingsForm.GeneralSettings.Stations.Split('|');
            foreach (string tmpStation in tmpStations)
            {
                AddStation(tmpStation);
            }
        }

        private void SaveStations()
        {
            string tmpStations = "";

            for (int i=0; i < stations.Count; i++)
            {
                if (tmpStations.Length == 0)
                {
                    tmpStations = stations.Values[i].Name;
                    stations.Values[i].SaveDepartures();
                }
                else
                {
                    tmpStations = tmpStations + "|" + stations.Values[i].Name;
                    stations.Values[i].SaveDepartures();
                }
            }

            settingsForm.GeneralSettings.Stations = tmpStations;
            settingsForm.GeneralSettings.saveSettings();

        }

        private void mniExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void mniRefresh_Click(object sender, EventArgs e)
        {
            if (mniRefresh.Text == "Refresh")
            {
                try
                {
                    if (tbcMain.TabPages[tbcMain.SelectedIndex].Name != "tbpMainCountdown")
                    {
                        stations[tbcMain.TabPages[tbcMain.SelectedIndex].Name].RefreshDepartures(); ;
                    }
                }
                catch (Exception ex)
                {
                    Cursor.Current = Cursors.Default;

                    MessageBox.Show(ex.Message, "An error occured");
                }
            }
            else if (mniRefresh.Text == "Stop")
            {
                ctrlCountdown.Stop();
                mniRefresh.Text = "";
                mniRefresh.Enabled = false;
            }
        }

        private void mniSettings_Click(object sender, EventArgs e)
        {
            settingsForm.ShowDialog();

            tmrRefresh.Enabled = settingsForm.GeneralSettings.AutoUpdate;
            tmrRemove.Enabled = settingsForm.GeneralSettings.RemovePastDepartures;

            skin = new SkinSettings(settingsForm.GeneralSettings.Skin + ".skin");
            skin.getSettings();

            foreach (ctrlStation station in stations.Values)
            {
                station.SkinSettings = skin;
            }
            ctrlCountdown.SkinSettings = skin;
        }

        private void tbcMain_SelectedIndexChanged(object sender, EventArgs e)
        {
            SetCursorButton();
            Application.DoEvents();
        }

        private void SetCursorButton()
        {
            if (tbcMain.TabPages[tbcMain.SelectedIndex].Name == "tbpMainCountdown")
            {

                Cursor.Current = Cursors.Default;
                ctrlCountdown.StartTimer();
                if (ctrlCountdown.isRunning)
                {
                    mniRefresh.Enabled = true;
                    mniRefresh.Text = "Stop";
                }
                else
                {
                    mniRefresh.Enabled = false;
                    mniRefresh.Text = "";
                }
            }
            else if (tbcMain.TabPages[tbcMain.SelectedIndex].Name == "tbpTest")
            {

            }
            else
            {
                mniRefresh.Text = "Refresh";

                if (stations[tbcMain.TabPages[tbcMain.SelectedIndex].Name].IsUpdating)
                {
                    Cursor.Current = Cursors.WaitCursor;
                    mniRefresh.Enabled = false;
                }
                else
                {
                    Cursor.Current = Cursors.Default;
                    mniRefresh.Enabled = true;
                }

                foreach (ctrlStation station in stations.Values)
                {
                    station.IsFocused = false;
                }

                stations[tbcMain.TabPages[tbcMain.SelectedIndex].Name].IsFocused = true;

                ctrlCountdown.StopTimer();
            }
        }

        private void tmrRefresh_Tick(object sender, EventArgs e)
        {
            for (int i = 0; i < stations.Count; i++)
            {
                if (!stations.Values[i].IsUpdating)
                {
                    stations.Values[i].RefreshDepartures();
                }
            }
        }

        private void tmrRemove_Tick(object sender, EventArgs e)
        {
            if (!backgroundWorkerRemove.IsBusy)
                backgroundWorkerRemove.RunWorkerAsync();
        }

        private void timerLoad_Tick(object sender, EventArgs e)
        {
            timerLoad.Enabled = false;
            LoadStations();
        }

        private void backgroundWorkerRemove_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i < stations.Count; i++)
            {
                if (!stations.Values[i].IsUpdating)
                {
                    stations.Values[i].RemovePastDepartures();
                }
            }
        }
                
        private void backgroundWorkerRemove_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
                throw e.Error;
        }

        private void ctrlCountdown_OnCountdownFinished()
        {
            if (tbcMain.SelectedIndex == 4)
            {
               mniRefresh.Enabled = false;
               mniRefresh.Text = "";
            }
                   
        }

        private void mniAddStation_Click(object sender, EventArgs e)
        {
            AddStation("");
            mniStationSettings_Click(this, EventArgs.Empty);
        }

        private void AddStation(string internalName)
        {
            TabPage tbpStation = new TabPage();
            tbpStation.Tag = "Station";
            if (internalName != "")
                tbpStation.Name = internalName;
            else
                tbpStation.Name = "Station" + DateTime.UtcNow.Ticks.ToString();

            ctrlStation station = new ctrlStation(tbpStation.Name, settingsForm.GeneralSettings, settings, vga);
            station.Name = tbpStation.Name;
            station.Dock = DockStyle.Fill;
            station.Parent = tbpStation;

            station.SkinSettings = skin;

            station.OnSetRefreshButton += new ctrlStation.SetRefreshButtonEventDelegate(station_OnSetRefreshButton);
            station.OnSetCountdown += new ctrlStation.SetCountdownEventDelegate(station_OnSetCountdown);

            station.HookKeyDown(tbcMain);

            if (station.StationSettings.Abbreviation != "")
                tbpStation.Text = station.StationSettings.Abbreviation;
            else
                tbpStation.Text = "New Station";

            lock (stations)
            {
                stations.Add(station.Name, station);
            }

            lock (tbcMain)
                tbcMain.TabPages.Insert(tbcMain.TabPages.Count - 1, tbpStation);

            station.LoadDepartures();

            if (internalName != "")
                tbcMain.SelectedIndex = 0;
            else
                tbcMain.SelectedIndex = tbcMain.TabPages.Count - 2;
        }

        void station_OnSetCountdown(string countdownTime, string train, string later)
        {
            if (countdownTime != "")
            {
                double correction = 0;
                if (later != "" && later.IndexOf("approx. ") >= 0)
                    correction = double.Parse(later.Replace("approx. ", "").Replace(" minutes later", ""));

                DateTime alarmTime = DateTime.FromFileTimeUtc(long.Parse(countdownTime)).AddMinutes(correction);

                ctrlCountdown.Start(alarmTime, train, later);
                tbcMain.SelectedIndex = tbcMain.TabPages.Count - 1;
            }
        }

        void station_OnSetRefreshButton(string internalName, bool enabled)
        {
            if (Invoking.GetTabPageNameAtSelectedIndex(tbcMain) == internalName)
            {
                Invoking.SetMenuItemEnabled(this, this.mniRefresh, enabled);
            }
        }

        private void mniRemoveStation_Click(object sender, EventArgs e)
        {
            if (tbcMain.TabPages[tbcMain.SelectedIndex].Name != "tbpMainCountdown")
            {
                if (MessageBox.Show("Do you really want to remove this station?","Remove Station", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
                {
                    lock (stations)
                    {
                        File.Delete(Utilities.AppPath() + "\\" + stations[tbcMain.TabPages[tbcMain.SelectedIndex].Name].Name + ".xml");

                        stations[tbcMain.TabPages[tbcMain.SelectedIndex].Name].StationSettings.removeSettings();
                        stations.RemoveAt(stations.IndexOfKey(tbcMain.TabPages[tbcMain.SelectedIndex].Name));
                    }
                    lock (tbcMain)
                        tbcMain.TabPages.RemoveAt(tbcMain.SelectedIndex);
                    tbcMain.SelectedIndex = 0;

                    SaveStations();
                }
            }
        }

        private void mniStationSettings_Click(object sender, EventArgs e)
        {
            if (tbcMain.TabPages[tbcMain.SelectedIndex].Name != "tbpMainCountdown")
            {
                stationSettingsForm.StationSettings = stations[tbcMain.TabPages[tbcMain.SelectedIndex].Name].StationSettings;
                stationSettingsForm.GeneralSettings = settingsForm.GeneralSettings;
                stationSettingsForm.ShowDialog();

                if (stations[tbcMain.TabPages[tbcMain.SelectedIndex].Name].StationSettings.Abbreviation != "")
                    tbcMain.TabPages[tbcMain.SelectedIndex].Text = stations[tbcMain.TabPages[tbcMain.SelectedIndex].Name].StationSettings.Abbreviation;

                stations[tbcMain.TabPages[tbcMain.SelectedIndex].Name].SetScaleDimensions();
            }
        }

        private void mniFullscreen_Click(object sender, EventArgs e)
        {
            if (this.mniFullscreen.Checked)
                SetFullScreen(false);
            else
                SetFullScreen(true);
        }

        private void SetFullScreen(bool fullScreen)
        {
            if (fullScreen)
            {
                this.WindowState = FormWindowState.Maximized;
                this.stationSettingsForm.WindowState = FormWindowState.Maximized;
                this.settingsForm.WindowState = FormWindowState.Maximized;
            }
            else
            {
                this.WindowState = FormWindowState.Normal;
                this.stationSettingsForm.WindowState = FormWindowState.Normal;
                this.settingsForm.WindowState = FormWindowState.Normal;
            }

            this.mniFullscreen.Checked = fullScreen;
            this.settingsForm.GeneralSettings.FullScreen = fullScreen;

            this.settingsForm.GeneralSettings.saveSettings();
        }

    }

    
}
